#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "inc/messagequeue.h"


// 初始化消息队列
MessageQueue* mq_init(int capacity) {
    MessageQueue* mq = (MessageQueue*)malloc(sizeof(MessageQueue));
    if (!mq) {
        perror("Failed to allocate message queue");
        return NULL;
    }
    
    mq->head = NULL;
    mq->tail = NULL;
    mq->size = 0;
    mq->capacity = capacity;
    mq->next_id = 0; // 初始化ID计数器
    
    if (pthread_mutex_init(&mq->mutex, NULL) != 0) {
        perror("Mutex init failed");
        free(mq);
        return NULL;
    }
    
    if (pthread_cond_init(&mq->not_empty, NULL) != 0 ||
        pthread_cond_init(&mq->not_full, NULL) != 0) {
        perror("Condition init failed");
        pthread_mutex_destroy(&mq->mutex);
        free(mq);
        return NULL;
    }
    
    return mq;
}

// 销毁消息队列
void mq_destroy(MessageQueue* mq) {
    if (!mq) return;
    
    pthread_mutex_lock(&mq->mutex);
    
    Message* current = mq->head;
    while (current) {
        Message* temp = current;
        current = current->next;
        free(temp);
    }
    
    pthread_mutex_unlock(&mq->mutex);
    pthread_mutex_destroy(&mq->mutex);
    pthread_cond_destroy(&mq->not_empty);
    pthread_cond_destroy(&mq->not_full);
    
    free(mq);
}

// 添加消息到队列
int mq_enqueue(MessageQueue* mq, const char* content) {
    if (!mq || !content) return -1;
    
    pthread_mutex_lock(&mq->mutex);
    
    // 等待队列有空闲空间
    while (mq->size >= mq->capacity) {
        pthread_cond_wait(&mq->not_full, &mq->mutex);
    }
    
    // 创建新消息
    Message* new_msg = (Message*)malloc(sizeof(Message));
    if (!new_msg) {
        pthread_mutex_unlock(&mq->mutex);
        perror("Failed to allocate message");
        return -1;
    }
    
    // 使用受保护的ID计数器
    new_msg->id = mq->next_id++;
    memcpy(new_msg->content, content, sizeof(new_msg->content) );
    new_msg->next = NULL;
    
    // 添加到队列尾部
    if (mq->tail) {
        mq->tail->next = new_msg;
        mq->tail = new_msg;
    } else {
        mq->head = mq->tail = new_msg;
    }
    
    mq->size++;
    
    // printf("Produced: ID=%d, Content=%s, Queue Size=%d\n", 
    //        new_msg->id, new_msg->content, mq->size);
    
    // 通知消费者有新消息
    pthread_cond_signal(&mq->not_empty);
    pthread_mutex_unlock(&mq->mutex);
    
    return 0;
}

// 从队列获取消息
Message* mq_dequeue(MessageQueue* mq) {
    if (!mq) return NULL;
    
    pthread_mutex_lock(&mq->mutex);
    
    // 等待队列不为空
    while (mq->size == 0) {
        pthread_cond_wait(&mq->not_empty, &mq->mutex);
    }
    
    // 从队列头部取出消息
    Message* msg = mq->head;
    if (mq->head == mq->tail) {
        mq->head = mq->tail = NULL;
    } else {
        mq->head = mq->head->next;
    }
    
    mq->size--;
    
    // printf("Consumed: ID=%d, Content=%s, Queue Size=%d\n", 
    //        msg->id, msg->content, mq->size);
    
    // 通知生产者有空闲空间
    pthread_cond_signal(&mq->not_full);
    pthread_mutex_unlock(&mq->mutex);
    
    return msg;
}

